iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
0
自我挑戰組

前端新手的學習筆記系列 第 23

Day23:每天一個小練習 - JS30-08-HTML5 Canvas

  • 分享至 

  • xImage
  •  

Alex老師教學

畫布效果。


先在HTML上使用<canvas>並規定範圍

<canvas id="draw" width="800" height="800"></canvas>

抓取節點後建立監聽

const canvas = document.querySelector('#draw');

canvas.addEventListener('mousedown', () => { //滑鼠按下觸發

})
canvas.addEventListener('mousemove', () => { //滑鼠移動

})
canvas.addEventListener('mouseup', () => { //滑鼠放開觸發

})
canvas.addEventListener('mouseout', () => { //滑鼠移開

})

加上繪圖的狀態控制項

let drawing = false;//不能立刻開始繪圖

canvas.addEventListener('mousedown', () => {
    //滑鼠按下觸發
    drawing =true;//開始繪圖
})
canvas.addEventListener('mousemove', () => {
    //滑鼠移動
    if (!drawing) { //狀態是false就不繼續執行
        return
    }
    console.log('draw')
})
canvas.addEventListener('mouseup', () => {
    //滑鼠放開觸發
    drawing =false;//停止繪圖
})
canvas.addEventListener('mouseout',() => {
    //滑鼠移開
    drawing = false //停止繪圖
})

此時可以在畫布上實驗,只有按住滑鼠移動才會觸發 console.log,放開滑鼠則停止。

呼叫getContext()方法,可依MDN上的介紹按需求調整參數

let ctx = canvas.getContext('2d');

加入各項要素調整線條內容

ctx.strokeStyle ='hsl(0,100%,50%)';//線條初始顏色
ctx.lineWidth = 100;//線條粗細
ctx.lineCap = 'round';//末端 - 圓角
ctx.lineJoin = "round";//轉折角- 圓角

開始製作繪圖效果

let x = 0,
    y = 0; // 點連到點就會連成線

canvas.addEventListener('mousedown', e => {
    //滑鼠按下觸發
    drawing = true; //開始繪圖
    [x, y] = [e.offsetX, e.offsetY];//座標
});
canvas.addEventListener('mousemove', () => {
    //滑鼠移動
    if (!drawing) {
        //狀態是false就不繼續執行
        return;
    }
    // console.log('draw');//確認觸發
    ctx.beginPath();//開始繪圖
		ctx.moveTo(x, y); //移動到所點擊的位置
    ctx.lineTo(e.offsetX, e.offsetY); //連到現在的位置
    [x, y] = [e.offsetX, e.offsetY];
    ctx.stroke();//繪製
});

以上設定好後已經可以繪製,可以到畫面測試是否成功
https://ithelp.ithome.com.tw/upload/images/20201007/201215345fEw64FMXE.png

加入自動變色

let colorDeg = 0; //存放顏色
ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`; //線條初始顏色
canvas.addEventListener('mousemove', e => {
    //滑鼠移動
(略)
    colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
    //如果小於360就+1,已經是360就變成0
    ctx.strokeStyle = `hsl(${colorDeg},100%,50%)`;
(略)
});

https://ithelp.ithome.com.tw/upload/images/20201007/2012153455yhAyjJfr.png

改變線條粗細

let lineWidth = 30;
let direction =-1;//方向
ctx.lineWidth = lineWidth; //線條粗細
canvas.addEventListener('mousemove', e => {
    //滑鼠移動
(略)
    // 粗細調整
    // lineWidth = lineWidth < 100 ? lineWidth + 1 : 50;//這樣的效果不同
    if (lineWidth < 1 || lineWidth > 100) { //臨界點切換
        direction *= -1;
    }
    lineWidth+=direction;
    ctx.lineWidth = lineWidth;
(略)
});

https://ithelp.ithome.com.tw/upload/images/20201007/201215342LzSNFXju7.png

透明度調整

let colorDeg = 0; //存放顏色
let alpha = 1; //透明度
let alphaDirection = 0.1; //透明度調整
ctx.strokeStyle = `hsla(${colorDeg},100%,0%,${alpha})`; //線條初始顏色

canvas.addEventListener('mousemove', e => {
    //滑鼠移動
(略)
    // 顏色調整
    colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
    //如果小於360就+1,已經是360就變成0
    if (alpha < 0.25 || alpha > 1) {
        //臨界點切換
        alphaDirection *= -1;
    }
    alpha += alphaDirection;
    ctx.strokeStyle = `hsla(${colorDeg},100%,70%,${alpha})`;
(略)
});

https://ithelp.ithome.com.tw/upload/images/20201007/20121534Km9q9MNLIB.png

超出畫面後回來的筆觸接續,全部監聽都要修改

//雙重判斷
let drawing = false; //不能立刻開始繪圖
let down = false; //是否點擊滑鼠

canvas.addEventListener('mousedown', e => {
    //滑鼠按下觸發
    // drawing = true; //開始繪圖
    down = true;
    [x, y] = [e.offsetX, e.offsetY]; //座標
});
canvas.addEventListener('mousemove', e => {
    //滑鼠移動
    // if (!drawing) {
    if (!down || !drawing) {
        //狀態是false就不繼續執行
        return;
    }
    // console.log('draw');//確認觸發

    ctx.beginPath(); //開始繪圖

    // 顏色調整
    colorDeg = colorDeg < 360 ? colorDeg + 1 : 0;
    //如果小於360就+1,已經是360就變成0
    if (alpha < 0.25 || alpha > 1) {
        //臨界點切換
        alphaDirection *= -1;
    }
    alpha += alphaDirection;
    ctx.strokeStyle = `hsla(${colorDeg},100%,70%,${alpha})`;

    // 粗細調整
    // lineWidth = lineWidth < 100 ? lineWidth + 1 : 50;//這樣的效果不同
    if (lineWidth < 1 || lineWidth > 50) {
        //臨界點切換
        direction *= -1;
    }
    lineWidth += direction;
    ctx.lineWidth = lineWidth;

    ctx.moveTo(x, y); //移動到所點擊的位置
    ctx.lineTo(e.offsetX, e.offsetY); //連到現在的位置
    [x, y] = [e.offsetX, e.offsetY];
    ctx.stroke(); //繪製
});
document.addEventListener('mouseup', () => {
    //任何地方放開都取消
    //滑鼠放開觸發
    // drawing = false; //停止繪圖
    down = false;
});
// canvas.addEventListener('mouseout', () => {
//     //滑鼠移開
//     drawing = false; //停止繪圖
// });
canvas.addEventListener('mouseleave', () => {
    //滑鼠移開
    drawing = false; //停止繪圖
});
canvas.addEventListener('mouseenter', e => {
    //滑鼠移動到元素上
    drawing = true;
    [x, y] = [e.offsetX, e.offsetY];
});

https://ithelp.ithome.com.tw/upload/images/20201007/20121534dXUsQU4ATO.png

連結


上一篇
Day22:每天一個小練習 - JS30-07-Array Cardio 02
下一篇
Day24:每天一個小練習 - JS30-09-Dev Tools Domination
系列文
前端新手的學習筆記32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言